use serde::Deserialize;
use std::{fs, sync::OnceLock};
use tracing::debug;

#[derive(Debug, Deserialize)]
pub struct Config {
	pub db_url: &'static str,
	pub db_max_conn_num: Option<u32>,
	pub log_path: Option<&'static str>,
	pub log_file_name: Option<&'static str>,
	pub log_to_file: Option<bool>,
	pub log_to_console: Option<bool>,
	pub log_level: Option<&'static str>,
	pub play_bell_path: &'static str,
	pub rec_path: &'static str,
	pub ftp_path: &'static str,
}

static CONFIG: OnceLock<Config> = OnceLock::new();

/**
 * 获取全局配置的静态引用。
 */
#[inline]
pub fn global_config() -> &'static Config {
	// 尝试获取或初始化配置信息
	CONFIG.get_or_init(|| load_config("./config/app.json"))
}

#[inline]
pub fn load_config<T>(path: &str) -> T
where
	T: Deserialize<'static>,
{
	debug!("开始读配置文件:{}", path);
	// 读取配置文件内容，如果文件不存在则抛出异常
	let content = fs::read_to_string(path).expect(r#"没有在指定的路径下找到配置文件。"#);

	// 将读取到的字符串转换为静态字符串..变成'static
	let config_raw: &'static str = Box::leak(content.into_boxed_str());

	// 将配置文件内容解析为Config结构体，如果解析失败则抛出异常
	let config = serde_json::from_str(config_raw).expect(r#"读配置文件出错,无法转换。"#);

	// 返回解析后的配置信息
	config
}
